<?php

declare(strict_types=1);

namespace App\Helpers;

use App\Job\ProcessImCallback;
use App\Job\ProcessOnlineStatusCallback;
use App\Model\AppChannel;
use App\Model\CoinLog;
use App\Model\Guild\GuildAccountDaily;
use App\Model\Guild\GuildHost;
use App\Model\Guild\GuildHostAccountDaily;
use App\Model\Guild\GuildManage;
use App\Model\PayOrder;
use App\Model\Stat\StatDaily;
use App\Model\Stat\StatDailyCall;
use App\Model\Stat\StatDailyCoin;
use App\Model\Stat\StatDailyHostInfo;
use App\Model\Stat\StatDailyPayInfo;
use App\Model\Stat\StatOnlineLog;
use App\Model\User;
use App\Model\UserActLog;
use App\Model\UserAutoMsg;
use App\Model\UserCancelLog;
use App\Model\UserCoin;
use App\Model\UserProfile;
use App\Model\UserProfilePersonal;
use App\Model\VideoCall;
use App\Model\Withdraw;
use Hyperf\AsyncQueue\Driver\DriverFactory;
use Hyperf\DbConnection\Db;
use Hyperf\Utils\ApplicationContext;

/**
 * 临时工具处理
 */
class TempTool
{
    /**
     * 检测异常金币流水
     */
    static function checkCoinLog($start = '', $end = '')
    {
        $where = [
            ['flag', 1],
            // ['log_type', CoinLog::TYPE_CONSUME]
        ];
        if ($start) $where[] = ['created_at', '>=', $start];
        if ($end) $where[] = ['created_at', '<', $end];
        $userIds = CoinLog::where($where)->pluck('user_id')->toArray();
        $userIds = array_unique($userIds);
        foreach ($userIds as $userId) {
            $profile = UserProfile::where('user_id', $userId)->first();
            $profileId = $profile->user_profile_id;
            $whereUser = array_merge($where, [['user_id', $userId]]);
            $data = CoinLog::where($whereUser)->get()->toArray();
            foreach ($data as $k => $log) {
                if ($log['log_type'] != CoinLog::TYPE_CONSUME || $k == 0) continue;
                $lastCoin = $data[$k - 1]['remain_income_coin'] + $data[$k - 1]['remain_recharge_coin'];
                $nowCoin = $log['remain_income_coin'] + $log['remain_recharge_coin'] + $log['coin'];
                if ($nowCoin != $lastCoin) {
                    echo "==LogId:{$log['id']}==Uid:{$userId}==ProfileId:{$profileId}==消耗：{$log['coin']}==剩余收入：{$log['remain_income_coin']}==剩余充值：{$log['remain_recharge_coin']}==时间：{$log['created_at']}==上次交易剩余：{$lastCoin}\n";
                }
            }
            // break;
        }
        return 1;
    }

    /**
     * 迁移自动打招呼消息
     */
    static function moveOldAutoMsg()
    {
        //文字消息
        $where = [
            ['auto_msg_text', '<>', ''],
            ['role', UserProfile::ROLE_HOST]
        ];
        $logs = UserProfile::where($where)->select(['user_id', 'auto_msg_text'])->get()->toArray();
        foreach ($logs as $log) {
            UserAutoMsg::addRecord($log['user_id'], 'text', $log['auto_msg_text']);
            echo "{$log['user_id']}=={$log['auto_msg_text']}\n";
        }

        //语音消息
        $where = [
            ['auto_msg_voice', '<>', ''],
            ['role', UserProfile::ROLE_HOST]
        ];
        $logs = UserProfile::where($where)->select(['user_id', 'auto_msg_voice', 'auto_voice_duration'])->get()->toArray();
        foreach ($logs as $log) {
            UserAutoMsg::addRecord($log['user_id'], 'voice', $log['auto_msg_voice'], $log['auto_voice_duration']);
            echo "{$log['user_id']}=={$log['auto_msg_voice']}=={$log['auto_voice_duration']}\n";
        }
    }

    static function setRongCloudTags($tags = ['male'], $regTimeStart = '', $regTimeEnd = '')
    {
        $where = [];
        if ($regTimeStart) $where[] = ['user_profile.created_at', '>=', $regTimeStart];
        if ($regTimeEnd) $where[] = ['user_profile.created_at', '<', $regTimeEnd];
        $accounts = Db::table('user_profile')->join('user', function ($join) {
            $where = [
                ['status', '=', User::STATUS_OK],
                ['is_official', 0],
                ['gender', 1],
                ['im_account', '<>', '']
            ];
            $join->on('user.id', '=', 'user_profile.user_id')->where($where);
        })->where($where)->orderBy('user.id', 'desc')->pluck('im_account')->toArray();
        $ret = ImUtil::setUserTags($accounts, $tags);
        return ['count' => count($accounts), 'ret' => $ret];
    }

    /**
     * 导出手机号
     */
    static function exportUserPhones($gender = -1, $filename = '', $role = 2)
    {
        // $payPhones = Db::table('user')->join('pay_order', function ($join) use ($gender) {
        //     $where = [
        //         ['user.status', '=', User::STATUS_OK],
        //         ['pay_order.status', '=', PayOrder::STATUS_OK],
        //         ['phone', '<>', '']
        //     ];
        //     if ($gender > -1) $where[] = ['gender', $gender];
        //     $join->on('user.id', '=', 'pay_order.user_id')->where($where)->whereRaw('locate("140000", phone)!=1');
        // })->pluck('phone')->toArray();
        // file_put_contents($filename, implode("\n", array_unique($phones)));

        $phones = Db::table('user_profile')->join('user', function ($join) use ($gender) {
            $where = [
                ['status', '=', User::STATUS_OK],
                ['is_official', 0],
                ['phone', '<>', ''],
                ['gender', $gender]
            ];
            $join->on('user.id', '=', 'user_profile.user_id')->where($where)->whereRaw('locate("140000", phone)!=1');
        })->pluck('phone')->toArray();
        file_put_contents($filename, implode("\n", array_unique($phones)));
    }

    static function fixMaleAvatar()
    {
        $where = [
            'gender' => 1,
            'avatar' => 'default/fe_avatar.jpeg',
            // ['user_id', '<', 20],
        ];
        $items = UserProfile::where($where)->get();
        foreach ($items as $item) {
            $avatar = UserProfile::pickAvatar(1);
            $item->update(['avatar' => $avatar]);
            $user = User::find($item->user_id);
            $ret = User::updateIMInfo($user->im_account, $item->nick_name, $avatar);
            echo "UserId:{$item->user_id}=={$avatar}==" . json_encode($ret);
        }
    }

    static function statGuildAccount($guildId = 0, $start = '')
    {
        $guild = GuildManage::getInfoByGuildId($guildId);
        if (!$guild) {
            echo "暂无该工会信息\n";
            return false;
        }
        $info['dt'] = $startTime = $start;
        $endTime = date('Y-m-d', strtotime($start) + 24 * 3600);
        $hostInfo = GuildHost::getHostIds($guild['id']);
        if (empty($hostInfo)) return;
        $hostIds = array_keys($hostInfo);
        //公会ID
        $info['guild_manage_id'] = $guild['id'];
        //计算当天活跃
        $info['active_host_num'] = UserActLog::checkActiveCount($hostIds, $startTime, $endTime);
        echo "当天活跃: {$info['active_host_num']}\n";
        //收益主播数量
        $incomeHostIds = CoinLog::checkHostCount($hostIds, $startTime, $endTime, 'uid');
        $info['income_host_num'] = count($incomeHostIds);
        echo "收益主播数量: {$info['income_host_num']}\n";
        //语音流水
        $info['voice_turnover'] = CoinLog::getTotalConsume($hostIds, $startTime, $endTime, [CoinLog::FROM_VOICECALL_OUT, CoinLog::FROM_QUICK_VOICE_OUT]);
        echo "语音流水: {$info['voice_turnover']}\n";
        //视频流水
        $info['video_turnover'] = CoinLog::getTotalConsume($hostIds, $startTime, $endTime, [CoinLog::FROM_VIDEOCALL_OUT, CoinLog::FROM_QUICK_VIDEO_OUT]);
        echo "视频流水: {$info['video_turnover']}\n";
        //私信流水
        $info['msg_turnover'] = CoinLog::getTotalConsume($hostIds, $startTime, $endTime, CoinLog::FROM_SEND_PRIVATE_MSG_OUT);
        echo "私信流水: {$info['msg_turnover']}\n";
        //礼物流水
        $info['gift_turnover'] =  CoinLog::getTotalConsume($hostIds, $startTime, $endTime, CoinLog::FROM_SEND_GIFT);
        echo "礼物流水: {$info['gift_turnover']}\n";
        //平台福利
        $info['free_turnover'] = CoinLog::getTotalIncome($hostIds, $startTime, $endTime, CoinLog::FROM_DAILY_FREE);
        echo "平台福利: {$info['free_turnover']}\n";
        //总流水（总消费）
        $info['total_turnover'] = CoinLog::getTotalConsume($hostIds, $startTime, $endTime);
        echo "总流水（总消费）: {$info['total_turnover']}\n";
        //主播总收入
        $info['host_total_share'] = CoinLog::getTotalIncome($hostIds, $startTime, $endTime);
        echo "主播总收入: {$info['host_total_share']}\n";
        //计算分成的部分（语音和视频）
        $shareTotal = $info['voice_turnover'] + $info['video_turnover'] + $info['msg_turnover'] + $info['gift_turnover'] + $info['free_turnover'];
        //主播分成（语音，视频，私信，普通礼物）
        $info['host_share_income'] = GuildManage::hostShareIncome($guild['host_share_ratio'], $shareTotal);
        //公会分成（语音，视频，私信，普通礼物）
        $info['guild_share_income'] = GuildManage::guildShareIncome($guild['guild_share_ratio'], $shareTotal);
        //添加记录
        echo "主播分成（语音，视频，私信，普通礼物）: {$info['host_share_income']}\n";
        echo "公会分成（语音，视频，私信，普通礼物）: {$info['guild_share_income']}\n";
        GuildAccountDaily::updateOrCreate([
            'guild_manage_id' => $guild['id'],
            'dt' => $info['dt']
        ], $info);
        self::statGuildHostAccount($guild, $incomeHostIds, $startTime, $endTime);
    }

    static function statGuildHostAccount($guild = 0, $hostIds, $startTime, $endTime)
    {
        $info['dt'] = $startTime;
        //公会ID
        $info['guild_manage_id'] = $guild['id'];
        // $guildBindTime = $guild['created_at'];
        $profiles = UserProfile::getUsersProfile($hostIds, true);
        array_walk($hostIds, function ($hostId, $key) use (&$info, $guild, $endTime, $startTime, $profiles) {
            $info['host_id'] = $hostId;
            //语音流水
            $info['voice_turnover'] = CoinLog::getTotalConsume([$hostId], $startTime, $endTime, [CoinLog::FROM_VOICECALL_OUT, CoinLog::FROM_QUICK_VOICE_OUT]);
            //视频流水
            $info['video_turnover'] = CoinLog::getTotalConsume([$hostId], $startTime, $endTime, [CoinLog::FROM_VIDEOCALL_OUT, CoinLog::FROM_QUICK_VIDEO_OUT]);
            //私信流水
            $info['msg_turnover'] = CoinLog::getTotalConsume([$hostId], $startTime, $endTime, CoinLog::FROM_SEND_PRIVATE_MSG_OUT);
            //礼物流水
            $info['gift_turnover'] = CoinLog::getTotalConsume([$hostId], $startTime, $endTime, CoinLog::FROM_SEND_GIFT);
            //平台福利
            $info['free_turnover'] = CoinLog::getTotalIncome([$hostId], $startTime, $endTime, CoinLog::FROM_DAILY_FREE);
            //总消费流水
            $info['total_turnover'] = $info['voice_turnover'] + $info['video_turnover'] + $info['msg_turnover'] + $info['gift_turnover'] + $info['free_turnover'];

            //工会主播分成比例
            // $hostShareRatio = $guild['host_share_ratio'];
            // $profile = UserProfile::getProfile($hostId);
            $hostShareRatio = $profiles[$hostId]['host_share'];
            //主播分成（语音和视频）
            $info['host_share_income'] = GuildManage::hostShareIncome($hostShareRatio, $info['total_turnover']);
            //语音分成
            $info['voice_share_income'] = GuildManage::hostShareIncome($hostShareRatio, $info['voice_turnover']);
            //视频分成
            $info['video_share_income'] = GuildManage::hostShareIncome($hostShareRatio, $info['video_turnover']);
            //总分成
            $info['total_share_income'] = CoinLog::getTotalIncome([$hostId], $startTime, $endTime);
            //最近上线时间
            $info['last_online_at'] = UserActLog::getLastOnlineTime($hostId, $startTime, $endTime);
            //主播签约该公会日期
            $info['binded_at'] = GuildHost::getBindTime($hostId, $guild['id']);

            echo "主播:{$key}\n";
            dump($info);
            //添加记录
            GuildHostAccountDaily::updateOrCreate([
                'host_id' => $info['host_id'],
                'dt' => $info['dt']
            ], $info);
        });
    }

    static function updateNewRechargeRmb($offDay = 10, $endDate = '', $channel = '')
    {
        for ($day = $offDay; $day > 0;) {
            $start = date('Y-m-d', strtotime("-{$day} day"));
            if ($start > $endDate) break;
            $day--;
            $end = date('Y-m-d', strtotime("-{$day} day"));
            $where = ['dt' => $start];
            if ($channel) $where['channel'] = $channel;
            else $where['channel'] = 'all';
            $model = StatDaily::where($where)->first();
            if (!$model) $model = new StatDaily();
            $model->dt = $start;
            // $model->channel = $channel;
            $channel == 'all' && $channel = '';
            $regUserIds = User::getRegUsers($start, $end, 'userId', $channel);
            $model->new_recharge_rmb = empty($regUserIds) ? 0 : PayOrder::getRechargeCoin($regUserIds, $start, $end, $channel, 'rmb');
            echo "{$start}:{$model->new_recharge_rmb}\n";
            $model->saveOrFail();
        }
    }

    /**
     * 流水记录TLS
     */
    static function addCoinLog($from = 10, $lmt = 1, $start = '', $end = '')
    {
        if (!$start || !$end) return false;
        $where = [
            ['created_at', '>', '2022-03-01'],
            ['coin', '>', 0]
        ];
        $where[] = ['from', $from];
        $data = CoinLog::where($where)->orderBy(Db::raw('rand()'))->limit(1000)->get()->toArray();
        if (empty($data)) return false;
        $addCoin = 0;
        for ($i = 0; $i < $lmt; $i++) {
            $item = $data[array_rand($data)];
            // $time = time() - mt_rand(48 * 3600, 336 * 3600);
            $time = mt_rand(strtotime($start), strtotime($end));
            $model = new CoinLog();
            $model->user_id = $item['user_id'];
            $model->from = $item['from'];
            $model->log_type = $item['log_type'];
            $addCoin += $model->coin = $item['coin'];
            $model->op_user_id = $item['op_user_id'];
            $logTime = date('Y-m-d H:i:s', $time);
            $model->remain_income_coin = self::getLatestRemain($item['user_id'], $logTime);
            $model->created_at = $model->updated_at = $logTime;
            $model->flag = 3;
            $ret = $model->saveOrFail();
            echo "New Add：{$item['coin']}\n";
        }
        echo "Total Add：{$addCoin}";
        return $ret;
    }

    /**
     * 邀请充值奖励记录TLS
     */
    static function addCoinLogInvite($userId = 0, $orderId = '')
    {
        $order = PayOrder::where('order_id', $orderId)->first();
        if (!$order || !$order->finished_at) {
            dump('暂无该订单信息或信息不匹配');
            return;
        }
        $payUserId = $order->user_id;
        $where = [
            'from' => CoinLog::FROM_INVITE_RECHARGE,
            'order_id' => $orderId,
        ];
        $logItem = CoinLog::where($where)->first();
        if ($logItem) {
            dump('该订单已经产生邀请奖励:Uid:' . $logItem->user_id);
            return;
        }
        $profile = UserProfile::getProfile($payUserId);
        if ((string)$profile->created_at > '2022-03-01') $invitePercent = 0.2;
        else $invitePercent = 0.1;

        //充值金币
        $totalRmb = $order->total_amount / 100;
        $totalCoin = $totalRmb * 10;
        $model = new CoinLog();
        $model->user_id = $userId;
        $model->from = CoinLog::FROM_INVITE_RECHARGE;
        $model->log_type = CoinLog::TYPE_INCOME;
        $model->coin = $invitePercent * $totalCoin;
        // $model->op_user_id = $payUserId;
        $logTime = (string)$order->finished_at;
        $model->remain_income_coin = self::getLatestRemain($userId, $logTime) + $model->coin;
        $model->created_at = $model->updated_at = $logTime;
        $model->flag = 3;
        $model->order_id = $orderId;
        $ret = $model->saveOrFail();
        dump('添加成功：' . $ret);
    }

    static function getLatestRemain($userId = 0, $logTime = '')
    {
        $where = [
            ['user_id', $userId],
            ['created_at', '>', $logTime]
        ];
        $item = CoinLog::where($where)->orderBy('created_at', 'desc')->first();
        return $item && $item->remain_income_coin ?: 0;
    }

    /**
     * AGST - 流水记录 - 矫正记录余额
     */
    static function updateRemainCoin($from = 10, $limit = 1000)
    {
        $where = [
            ['flag', 3],
            ['remain_income_coin', 0]
        ];
        $where[] = ['from', $from];
        $data = CoinLog::where($where)->orderBy('created_at', 'desc')->limit($limit)->select(['id', 'coin'])->get()->toArray();
        if (empty($data)) return false;
        foreach ($data as $item) {
            $remain = mt_rand(intval($item['coin']), 2000);
            CoinLog::where('id', $item['id'])->limit(1)->update(['remain_income_coin' => $remain]);
            echo "LogId:{$item['id']}==Coin:{$item['coin']}==Remain:{$remain}\n";
        }
    }

    static function updateRongCloudInfo()
    {
        $startUid = env('RONG_NEW_START_UID', 803);
        for ($userId = $startUid; $userId > 0; $userId--) {
            $profile = UserProfile::getProfile($userId);
            if (!$profile) continue;
            $ret = User::createRongIMAccount($userId, $profile->nick_name, $profile->avatar);
            echo "Uid:{$userId}==" . json_encode($ret) . "\n";
        }
        return;
    }

    /**
     * 批量绑定工会主播
     */
    static function batchAddToGuild($hostIds = [], $guildId = 0)
    {
        $info = [];
        $info['guild_manage_id'] = $guildId;
        foreach ($hostIds as $profileId) {
            $check = UserProfile::where(['user_profile_id' => $profileId])->first();
            if (!$check) {
                dump("没有主播信息：{$profileId}");
                continue;
            }
            //是否绑定过该主播
            $hostId = $check->user_id;
            $gId = GuildHost::getGuildId($hostId);
            if ($gId > 0) {
                dump("已经绑定过：{$profileId}=Gid:{$gId}");
                continue;
            }
            $info['host_user_id'] = $hostId;
            $info['host_profile_id'] = $profileId;
            //认证状态
            $info['verf_status'] = UserProfilePersonal::isFaceVerified($hostId);
            $info['status'] = GuildHost::STATUS_BIND;
            GuildHost::updateOrCreate([
                'guild_manage_id' => $guildId,
                'host_user_id' => $hostId
            ], $info);
            dump("绑定成功：{$profileId}");
        }
    }

    /**
     * 工会日报数据
     */
    static function updateGuildAccountDaily($dt = '', $guildId = 0, $ratio = 0.9)
    {
        if (!$dt) return false;
        $where = ['dt' => $dt];
        $guildId > 0 && $where['guild_manage_id'] = $guildId;
        $data = GuildAccountDaily::where($where)->get()->toArray();
        $fields = ['voice_turnover', 'video_turnover', 'msg_turnover', 'gift_turnover', 'free_turnover', 'total_turnover', 'guild_share_income'];
        foreach ($data as $item) {
            $guild = GuildManage::find($guildId)->toArray();
            $info = [];
            foreach ($fields as $field) {
                $info[$field] = round($item[$field] * $ratio, 1);
            }
            $shareTotal = $info['voice_turnover'] + $info['video_turnover'] + $info['msg_turnover'] + $info['gift_turnover'] + $info['free_turnover'];
            $info['guild_share_income'] = GuildManage::guildShareIncome($guild['guild_share_ratio'], $shareTotal);
            $ret = GuildAccountDaily::where('id', $item['id'])->limit(1)->update($info);
            dump("更新工会{$guildId}=={$ret}==GuildShare:{$guild['guild_share_ratio']}==" . json_encode($info));
        }
    }

    /**
     * 矫正部分消费金币数
     */
    static function updateConsumeCoin($start = '2022-02-18', $end = '2022-02-19')
    {
        $channels = AppChannel::getAllChannels();
        foreach ($channels as $channel) {
            $where = ['dt' => $start, 'channel' => $channel];
            $model = StatDaily::where($where)->first();
            if (!$model) continue;
            $model->consume_coin = CoinLog::getConsumeCount($start, $end, 'coin', $channel);
            $model->saveOrFail();
            dump("{$channel}=={$model->consume_coin}");
        }
    }

    /**
     * 解除冻结账户金币
     */
    static function unfreezeCoin()
    {
        $logs = VideoCall::getChatting();
        $userIds = [];
        foreach ($logs as $log) {
            $userIds[] = $log['user_id'];
            $userIds[] = $log['chat_user_id'];
        }
        $userIds = array_unique($userIds);

        //恢复冻结资金
        $where = [['freeze_coin', '>', 0]];
        $data = UserCoin::where($where)->whereNotIn('user_id', $userIds)->pluck('freeze_coin', 'user_id')->toArray();
        $ret = UserCoin::where($where)->whereNotIn('user_id', $userIds)->update(['freeze_coin' => 0]);
        dump($data);
        dump($ret);
    }

    /**
     * 迁移老数据到新包
     */
    static function moveDataToNew()
    {
        $data = Db::select('select * from t_user_msg_log_tmp order by id desc limit 1');
    }

    static function testPushRongMsg($key = 'jikeliao')
    {
        $msg = '{"0":{"userid":"ef24563d5bcb314f8322502573dac09a","status":"1","os":"Android","time":1645614465379,"clientIp":"113.104.210.12:12375"},"timestamp":"1645614466424","signTimestamp":"1645614466424","nonce":"1906485180","signature":"e37ce696e999c6451babd8805505ffa134c91b28","appKey":"mgb7ka1nme9ig"}';
        $msg = json_decode($msg, true);
        $queDriver = ApplicationContext::getContainer()->get(DriverFactory::class)->get($key);
        $ret = $queDriver->push(new ProcessOnlineStatusCallback($msg), 0);
        return $ret;
    }

    /**
     * 收支明细
     */
    static function coinDetail($start = '2022-02-01', $end = '2022-03-01', $logType = CoinLog::TYPE_INCOME)
    {
        $data = Db::select("SELECT `from`, SUM(coin) AS s FROM t_coin_log WHERE created_at<'" . $end . "' and created_at>'" . $start . "' and `log_type`=" . $logType . " GROUP BY `from` ORDER BY s DESC");
        $ret = [];
        foreach ($data as $item) {
            $ret[CoinLog::FROM_DETAIL[$item->from]] = round($item->s, 1);
        }
        dump($ret);
    }

    /**
     * 独立包更新IM账号
     */
    static function changeImAccounts()
    {
        $excludeUids = [];
        $users = User::whereNotIn('id', $excludeUids)->get()->toArray();
        foreach ($users as $user) {
            $profile = UserProfile::getProfile($user['id']);
            $ret = User::createRongIMAccount($user['id'], $profile->name, $profile->avatar);
            dump("{$user['id']}==" . json_encode($ret));
        }
    }

    /**
     * 统计常规话单（分渠道）
     */
    static function statCallChannel($start = 20, $end = 0)
    {
        $callType = VideoCall::CALL_TYPE;
        //常规
        $callSubType = 1;
        $subType = StatDailyCall::SUB_TYPE[$callSubType];
        $callCls = VideoCall::class;
        for ($day = $start; $day >= $end;) {
            $startDt = date('Y-m-d', strtotime("-{$day} day"));
            $endDt = date('Y-m-d', strtotime("-" . (--$day) . " day"));
            $channels = AppChannel::getAllChannels();
            foreach ($channels as $channel) {
                $where = [
                    'dt' => $startDt,
                    'call_type' => $callType,
                    'call_subtype' => $callSubType //常规
                ];
                $callFrom = $subType['from'];
                $model = $callCls::where($where)->first();
                $model->call_num = $callCls::getCallNum('all', $startDt, $endDt, $callFrom, 0, 0, $channel);
                $model->success_num = $callCls::getCallNum('success_num', $startDt, $endDt, $callFrom);
                // $model->caller_num = $callCls::getCallNum('caller_num', $startDt, $endDt, $callFrom);
                // $model->receiver_num = $callCls::getCallNum('receiver_num', $startDt, $endDt, $callFrom);
                // $model->success_caller_num = $callCls::getCallNum('success_caller_num', $startDt, $endDt, $callFrom);
                // $model->success_receiver_num = $callCls::getCallNum('success_receiver_num', $startDt, $endDt, $callFrom);
                // $model->total_call_time = $callCls::getCallNum('total_call_time', $startDt, $endDt, $callFrom);
                dump([
                    // 'channel' => 
                ]);
            }
        }
    }

    /**
     * 统计数据
     */
    static function statData($start = '2022-02-01', $end = '2022-03-01', $logType = CoinLog::TYPE_INCOME)
    {
        $where = [
            ['created_at', '>', $start],
            ['created_at', '<', $end],
            ['log_type', $logType]
        ];
        $data = CoinLog::where($where)->select(Db::raw('SUM(coin) as s, `from`'))->groupBy('from')->orderBy('s', 'desc')->get()->toArray();
        $ret = [];
        foreach ($data as $item) {
            $ret[CoinLog::FROM_DETAIL[$item['from']]] = round($item['s'], 2);
        }
        dump($ret);
    }

    /**
     * 在线人数
     */
    static function statOnlineInfo($start = '2022-02-01', $end = '2022-03-01')
    {
        $where = [
            ['created_at', '>', $start],
            ['created_at', '<', $end],
        ];
        $data = StatOnlineLog::where($where)->get()->toArray();
        foreach ($data as $item) {
            $time = date('Y-m-d H:i', strtotime($item['created_at']));
            $str = "{$time}  男：{$item['online_male_num']}  女：{$item['online_female_num']}\n";
            file_put_contents('online.txt', $str, FILE_APPEND);
        }
    }

    /**
     * 支付宝账号错误
     */
    static function updateAlipayAccountError($yzhOrderId = [])
    {
        if (!$yzhOrderId) {
            dump('ID错误');
            return;
        }
        !is_array($yzhOrderId) && $yzhOrderId = [$yzhOrderId];
        $detail = '{"status":"261","message":"失败","detail":"支付宝账号错误"}';
        $ret = Withdraw::whereIn('yzh_order_id', $yzhOrderId)->limit(count($yzhOrderId))->update(['status' => Withdraw::STATUS_YZH_ERR, 'yzh_detail' => $detail]);
        dump($ret);
    }

    /**
     * 修复充值订单
     */
    static function fixPayOrder($start = 20, $end = 0)
    {
        for ($day = $start; $day >= $end;) {
            $startDt = date('Y-m-d', strtotime("-{$day} day"));
            $endDt = date('Y-m-d', strtotime("-" . (--$day) . " day"));
            echo "fixPayOrder=={$startDt}=={$endDt}\n";
            $where = [
                ['finished_at', '>', $startDt],
                ['finished_at', '<', $endDt],
            ];
            $extraWhere = array_merge($where, [['status', PayOrder::STATUS_EXTRA]]);
            dump($extraWhere);
            $extraUids = PayOrder::where($where)->pluck('user_id')->toArray();
        }
    }

    static function getCityUserPayInfo($limit = 10)
    {
        $city = '深圳市';
        $data = Db::select('select user_id, round(sum(total_amount)/100, 0) as s, phone from t_pay_order p join t_user u on p.user_id=u.id where p.status in(1,4) and user_id in(select distinct user_id from t_user_profile where locate_city="' . $city . '" and gender=1) group by user_id limit ' . $limit);
        foreach ($data as $item) {
            $profile = UserProfile::where('user_id', $item->user_id)->first();
            $str = "{$profile->user_profile_id}\t{$item->s}\t{$item->phone}\n";
            file_put_contents('sz_pay_phone.xls', $str, FILE_APPEND);
        }
    }

    /**
     * 修复收入
     */
    static function fixStatDailyIncome($start = '', $end = '', $fixReal = true, $percent = 0.5)
    {
        !$end && $end = date('Y-m-d');
        for ($i = 0;; $i++) {
            $dt = date('Y-m-d', strtotime($start) + $i * 24 * 3600);
            $endDt = date('Y-m-d', strtotime($start) + ($i + 1) * 24 * 3600);
            if ($dt > $end) break;
            $where = [
                'channel' => 'all',
                'dt' => $dt
            ];
            if ($fixReal) {
                $income = CoinLog::getTotalIncome(StatDailyHostInfo::getActiveHosts($dt), $dt, $endDt);
                echo "{$dt}收入：{$income}\n";
                StatDaily::where($where)->limit(1)->update(['income_coin' => $income]);
            } else {
                $offIncome = PayOrder::getExtraTotal($dt, $endDt) * 10 * $percent;
                echo "{$dt}减少：{$offIncome}\n";
                StatDaily::where($where)->limit(1)->decrement('income_coin', $offIncome);
            }
        }
        return '==End==';
    }

    /**
     * 消费金额
     */
    static function fixConsumeCoin($dt = '', $offCoin = 1000)
    {
        $where = [
            'channel' => 'all',
            'dt' => $dt
        ];
        $ret = StatDaily::where($where)->limit(1)->decrement('consume_coin', $offCoin);
        dump($ret);
    }

    /**
     * 消费金额
     */
    static function fixDailyRecharge($start = '', $end = '')
    {
        !$end && $end = date('Y-m-d');
        for ($i = 0;; $i++) {
            $dt = date('Y-m-d', strtotime($start) + $i * 24 * 3600);
            $endDt = date('Y-m-d', strtotime($start) + ($i + 1) * 24 * 3600);
            if ($dt > $end) break;
            $where = [
                'channel' => 'all',
                'dt' => $dt
            ];
            $rechargeCoin = PayOrder::getRechargeCoin([], $dt, $endDt, '');
            $rechargeRmb = PayOrder::getRechargeCoin([], $dt, $endDt, '', 'rmb');
            echo "{$dt}充值金额：{$rechargeRmb}\n";
            StatDaily::where($where)->limit(1)->update([
                'recharge_rmb' => $rechargeRmb,
                'recharge_coin' => $rechargeCoin
            ]);
        }
        return '==End==';
    }

    static function getCallrank($start = '', $end = '')
    {
        // $mondayTs = (time() - ((date('w') == 0 ? 7 : date('w')) - 1) * 24 * 3600);
        // $sundayTs = (time() + (date('w') == 0 ? 0 : (7 - date('w'))) * 24 * 3600);
        // $monday = date('Y-m-d', $mondayTs);
        // $sunday = date('Y-m-d', $sundayTs);
        $rankList = StatDailyHostInfo::getCallRankList(10, $start, $end);
        $userIds = array_column($rankList, 'user_id');
        $userProfiles = UserProfile::getUsersProfile($userIds, true);
        foreach ($rankList as $k => $item) {
            $uid = $item['user_id'];
            $profile = $userProfiles[$uid];
            $callMins = $item['call_minutes'];
            echo "{$profile['nick_name']}(ID: {$profile['user_profile_id']}) 通话：{$callMins}分钟\n";
        }
    }

    static function pushCallBack($redisKey = 'jikeliao')
    {
        $callbackInfo = '{"channelType":"PERSON","fromUserId":"jikeliao_c06df4d4c9e8a19a99f9dcdfc942c618","toUserId":"cf3ed6b26119bce2e744a505ff8ff6fd","msgTimestamp":"1650616249042","timestamp":"1650616249079","objectName":"RC:TxtMsg","content":"{\"content\":\"\u6d51\u8eab\u89e3\u6570\",\"user\":{\"id\":\"482\",\"name\":\"\u521a\u6bc5\u7684\u8682\u8681\",\"portrait\":\"http:\\\/\\\/jitian-photo.oss-cn-shenzhen.aliyuncs.com\\\/default\\\/a-248.jpg?x-oss-process=image\\\/resize,m_fill,h_500,w_500\"},\"isBurnAfterRead\":false,\"burnDuration\":0}","sensitiveType":"0","source":"Android","msgUID":"C0A1-IILK-K0C4-ALQF","msgRandom":"432699146299508824","signTimestamp":"1650616249079","nonce":"1886461683","signature":"97d1923a0b0c7ba056e251b0d50fafbe4efddf76","appKey":"8w7jv4qb8ztly"}';
        $queDriver = ApplicationContext::getContainer()->get(DriverFactory::class)->get($redisKey);
        $callbackInfo = json_decode($callbackInfo, true);
        $ret = $queDriver->push(new ProcessImCallback($callbackInfo));
        return $ret;
    }

    static function updateGuildHostCoinSetting($guildId = 0, $videoCoin = 20, $voiceCoin = 10, $msgCoin = 2)
    {
        $hostIds = array_keys(GuildHost::getHostIds($guildId));
        $count = count($hostIds);
        $where = [
            // ['video_coin_setting', '<', $videoCoin]
        ];
        UserProfile::whereIn('user_id', $hostIds)->where($where)->limit($count)->update([
            'video_coin_setting' => $videoCoin,
            'coin_setting' => $voiceCoin,
            'chat_coin_setting' => $msgCoin,
        ]);
        dump("更新工会：{$guildId}一共{$count}人");
        return '===更新完成===';
    }

    /**
     * 自动注销账号
     */
    static function autoCancelAccount($expDays = 3, $limit = 10)
    {
        // $expDays = 3;
        $userIds = UserCancelLog::getLogs(UserCancelLog::FLAG_ING, date('Y-m-d', strtotime("-{$expDays} day")));
        if (empty($userIds)) return;
        foreach ($userIds as $userId) {
            //更新状态
            $ret = UserCancelLog::where('user_id', $userId)->update(['flag' => UserCancelLog::FLAG_OK]);
            //注销账号
            User::cancelAccount($userId);
            dump("UserId:{$userId}");
        }
    }

    /**
     * 充值日报-邀请和非邀请金额
     */
    static function updateInviteRechargeInfo($start = '', $end = '')
    {
        !$end && $end = date('Y-m-d');
        for ($i = 0;; $i++) {
            $dt = date('Y-m-d', strtotime($start) + $i * 24 * 3600);
            $endDt = date('Y-m-d', strtotime($start) + ($i + 1) * 24 * 3600);
            if ($dt > $end) break;
            $info = [
                'dt' => $dt,
                'invite_rmb_num' => PayOrder::getInviteData($dt, $endDt, true, 'rmb'),
                'uninvite_rmb_num' => PayOrder::getInviteData($dt, $endDt, false, 'rmb'),
                'invite_user_num' => PayOrder::getInviteData($dt, $endDt, true, 'user'),
                'uninvite_user_num' => PayOrder::getInviteData($dt, $endDt, false, 'user')
            ];
            StatDailyPayInfo::updateOrCreate(['dt' => $dt], $info);
            echo "{$dt}更新==" . json_encode($info) . "\n";
        }
        return '==End==';
    }

    /**
     * 真人
     */
    static function avatarVrfy($profileId = 0)
    {
        return UserProfile::where('user_profile_id', $profileId)->limit(1)->update(['avatar_vrfy' => 1]);
    }
}
